#include "statistics.h"

void Statistics::update_info(InfoRect& info_new)
{
	info.info_update(info_new);

	//update_info();

	if (info.flag == 1)
	{
		update_gender_info();
		update_age_info();
		update_id_info();

		if (total_info.person_in.size() < total_info.limit_size)
		{
			total_info.person_in.push_back(info);
		}
		else
		{
			total_info.person_in.erase(total_info.person_in.begin());
			total_info.person_in.push_back(info);
		}
		
		++total_info.num_in_per10min[total_info.time_index];
		++total_info.num_in;
		info.has_in = true;
		info.has_out = false;
	}
	else if (info.flag == -1)
	{
		++total_info.num_out;
		
		++info.out_order;
		if (total_info.person_out.size() < total_info.limit_size)
		{
			total_info.person_out.push_back(info);
		}
		else
		{
			total_info.person_out.erase(total_info.person_out.begin());
			total_info.person_out.push_back(info);
		}
		info.has_in = false;
		info.has_out = true;
	}
	info_new.info_update(info,true);
}

void Statistics::update_info(std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>* time)
{
	//update time
	std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes> time_now;
	if(time!=nullptr)
		time_now = std::chrono::time_point_cast<std::chrono::minutes>(*time);
	else
		time_now = std::chrono::time_point_cast<std::chrono::minutes>(std::chrono::system_clock::now());
	std::time_t tt = std::chrono::system_clock::to_time_t(time_now);
	tm* tm = std::localtime(&tt);

	if (previous_time != nullptr)
	{
		if (tm->tm_mday != previous_time->tm_mday)
		{
			total_info.num_in_per10min.clear();
			total_info.num_in_per10min.resize(114, 0);
		}
	}

	total_info.time_index = tm->tm_hour * 6 + tm->tm_min / 10;
	if (previous_time == nullptr)
		previous_time = std::localtime(&tt);

	*previous_time = *tm;
}

void Statistics::update_id_info()
{
	std::string person_id_cur = "Unknow";

	std::string person_id_max = "Unknow";
	float person_score_max = 0.0f;
	for (int i = 0; i < info.person_info.size(); ++i)
	{
		if (info.person_info[i].second > person_score_max)
		{
			person_score_max = info.person_info[i].second;
			person_id_max = info.person_info[i].first;
			//cout << person_id_cur << " score " << person_score_cur << endl;
		}
	}

	if (person_score_max >= 0.65f)
	{
		person_id_cur = person_id_max;
	}
	else
	{
		//if three times indict one person
		if (info.person_info.size() == 3)
		{
			if (info.person_info[0].first == info.person_info[1].first
				&& info.person_info[0].first == info.person_info[2].first)
			{
				//all same
				if (person_score_max>threshold+0.05)
					person_id_cur = person_id_max;
			}
			else if (info.person_info[0].first == info.person_info[1].first && info.person_info[0].first == person_id_max)
			{
				//first 2 are same
				if (person_score_max>threshold+0.1)
					person_id_cur = person_id_max;
			}
			else if (info.person_info[0].first == info.person_info[2].first && info.person_info[0].first == person_id_max)
			{
				if (person_score_max>threshold + 0.1)
					person_id_cur = person_id_max;
			}
			else if (info.person_info[1].first == info.person_info[2].first && info.person_info[1].first == person_id_max)
			{
				if (person_score_max>threshold + 0.1)
					person_id_cur = person_id_max;
			}
			else
			{
				if (person_score_max>threshold + 0.15)
					person_id_cur = person_id_max;
			}
		}
		else if (info.person_info.size() == 2)
		{
			if (info.person_info[0].first == info.person_info[1].first)
			{
				if (person_score_max>threshold + 0.1)
					person_id_cur = person_id_max;
			}
			else
			{
				if (person_score_max>threshold + 0.15)
					person_id_cur = person_id_max;
			}
		}
		else
		{
			if (person_score_max>threshold + 0.15)
				person_id_cur = person_id_max;
		}
	}

	info.person_id = person_id_cur;
	info.is_vip = person_id_cur == "Unknow" ? false : true;

	if (info.is_vip)
	{
		++total_info.vip_in;
		++info.vip_order;
	}
	else
	{
		++info.non_vip_order;
		++total_info.non_vip_in;
	}
}

void Statistics::update_gender_info()
{
	int malecount = 0;
	int femalecount = 0;
	std::string str_temp;
	for (int j = 0; j < 3; j++) {
		if (info.gender[j] == 0) {
			femalecount++;
		}
		else if (info.gender[j] == 1) {
			malecount++;
		}
		//std::cout << "info.gender[j]" << info.gender[j] << std::endl;
	}
	if (femalecount < malecount) {
		++total_info.male_in;
		info.gender_s = "male";
	}
	else {
		++total_info.female_in;
		info.gender_s = "female";
	}
}

void Statistics::update_age_info()
{
	if (info.face_detect_times = 0)
		return;

	info.age_flag = std::distance(info.ages.begin(), std::max_element(info.ages.begin(), info.ages.end()));

	++total_info.age_sum[info.age_flag];
}